﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LorraineSec.ServerApplication
{
    /// <summary>
    /// Use this object to handle a list coupled with a list sort text edit.
    /// </summary>
    public sealed class ListSelectSorter
    {
        private ListBox ListGUI;
        private TextBox SortEdit;

        /// <summary>
        /// Constructs a ListSelectSorter
        /// </summary>
        /// <param name="list">The ListBox component to attach to.</param>
        /// <param name="sort">The TextBox component to attach to.</param>
        public ListSelectSorter(ListBox list, TextBox sort)
        {
            ListGUI = list;
            SortEdit = sort;
            SortEdit.TextChanged += new EventHandler(SortTextChanged);
        }

        private void SortTextChanged(object sender, EventArgs args)
        {
            ListBox.ObjectCollection col = ListGUI.Items;
            int curIdx = 0;
            int phraseIdx = 0;
            string sortPhrase = SortEdit.Text.ToLower();
            //For each letter in the sort phrase
            if (sortPhrase.Length > 0)
            {
                foreach (char c in sortPhrase)
                {

                    while (curIdx < col.Count)
                    {
                        //Index to the correct character in the current objects string representation
                        char x = col[curIdx].ToString()[phraseIdx];
                        //If the characters are equal
                        if (c == x || c == x + 32)
                            break;
                        //Increment current object index
                        ++curIdx;
                    }
                    //Increment the search phrase index
                    ++phraseIdx;
                }
                //Change the selection in the list
                ListGUI.SelectedIndices.Clear();
                if (curIdx < col.Count)
                    ListGUI.SelectedIndex = curIdx;
            }
            else
            {
                ListGUI.SelectedIndices.Clear();
            }
        }
    }

    /// <summary>
    /// A standalone list select GUI.
    /// </summary>
    public sealed partial class ListSelectForm : Form
    {
        private ListSelectSorter ListSorter;

        private ListSelectForm(object[] sList)
        {
            InitializeComponent();
            this.KeyPreview = true;
            selectList.Items.AddRange(sList.ToArray());

            ListSorter = new ListSelectSorter(selectList, SortEdit);
        }

        /// <summary>
        /// Generates a selection list and blocks until the form closes.
        /// </summary>
        /// <param name="title">The title of the selection form.</param>
        /// <param name="sList">The list of objects to select from.</param>
        /// <param name="idx">The default index in the list.</param>
        /// <returns>The selected object from the list.</returns>
        public static object getSelectionFromList(string title, object[] sList, int idx)
        {
            ListSelectForm t = new ListSelectForm(sList);
            t.Text = title;
            t.setIndex(idx);
            t.ShowDialog();
            return t.selectList.SelectedItem;
        }

        private void selectButton_Click(object sender, EventArgs e)
        {
            if (this.selectList.SelectedItem != null)
                Close();
        }

        private void setIndex(int idx)
        {
            if (selectList.Items.Count > 0 && idx >= 0 && idx < selectList.Items.Count)
            {
                selectList.SelectedIndex = idx;
            }
            else
            {
                selectList.SelectedIndex = 0;
            }
        }

        private void selectList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            selectButton_Click(null, null);
        }

        private void ListSelect_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    this.selectList.SelectedIndex = -1;
                    Close();
                    break;
                case Keys.Enter:
                    selectButton_Click(null, null);
                    break;
            }
        }
    }   
}
